package com.hipac.hq;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.PsiJavaFileImpl;
import com.intellij.psi.impl.source.javadoc.PsiDocTokenImpl;

/**
 * 将java Bean属于转成 json，并带上注释，主要是为了解决给前端提供数据结构的问题
 *
 * @author huqiang
 * @since 2018/11/8 4:29 PM
 */
public class Bean2JsonNonValue extends AnAction {
	private static final Logger LOG = Logger.getInstance(Bean2JsonNonValue.class);

	@Override
	public void actionPerformed(AnActionEvent anActionEvent) {
		PsiElement psiElement = getPsiElement(anActionEvent);
		//		((PsiJavaFileImpl)e.getData(LangDataKeys.PSI_FILE).getOriginalFile().getNavigationElement()).getClasses()[0].getFields()
		generateO2OMethod(psiElement);
	}


	/**
	 * 启动写线程
	 *
	 * @param psiElement
	 */
	private void generateO2OMethod(final PsiElement psiElement) {
		new WriteCommandAction.Simple(psiElement.getProject(), psiElement.getContainingFile()) {
			@Override
			protected void run() throws Throwable {
				buildJson(psiElement);
			}
		}.execute();
	}

	private void buildJson(PsiElement psiElement) {
		PsiJavaFileImpl javaFile = null;
		if (psiElement instanceof PsiJavaFileImpl) {
			javaFile = (PsiJavaFileImpl) psiElement;
		}
		if (javaFile == null) {
			return;
		}
		PsiField[] fields = javaFile.getClasses()[0].getFields();
		if (fields == null) {
			return;
		}
		StringBuilder sb = new StringBuilder();
		sb.append("{");
		for (PsiField field : fields) {
			PsiType type = field.getType();
			sb.append("\n");
			sb.append("\"").append(field.getName()).append("\"").append(": ");
			if (type instanceof PsiClassReferenceType){
				String referenceName = ((PsiClassReferenceType) type).getReference().getReferenceName();
				if (referenceName.equals("Integer")||referenceName.equals("Long")){
					sb.append("null");
				}else if(referenceName.equals("Boolean")){
					sb.append("null");
				}
				else if (referenceName.equals("String")){
					sb.append("\"");
					sb.append("\"");
				}
				else {
					sb.append("\"");
					sb.append("\"");
				}
			}else if (type instanceof PsiType){
				LOG.info(field.getName()+"  "+type);
				if (type.equalsToText(PsiType.LONG.getName())){
					sb.append("2");
				}else if (type.equals(PsiType.INT)){
					sb.append("1");
				}else if(type.equals(PsiType.BOOLEAN)){
					sb.append("true");
				}
				else{
					sb.append("\"");
					sb.append("\"");
				}
			}
			sb.append(",");
			sb.append("//").append(format(field));
		}
		String s=sb.append("\n").append("}").toString();
		int idx=s.lastIndexOf(",");
		s=s.substring(0,idx)+s.substring(idx+1,s.length());
		PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiElement.getProject());
		PsiCodeBlock codeBlock = elementFactory.createCodeBlockFromText(s,psiElement);
		javaFile.add(codeBlock);
	}


	private String format(PsiField field) {
		String oldContent = "";
		if (field.getDocComment() == null) {
			//  //单行注释 \n private String a;
			if (field.getText().lastIndexOf("\n")==-1){
				return "";
			}
			oldContent = field.getText().substring(0, field.getText().lastIndexOf("\n") + 1).replace("//","").replaceAll("\n","");
		} else {
			PsiElement[] descriptionElements = field.getDocComment().getDescriptionElements();

			for (PsiElement descriptionElement : descriptionElements) {
				if (descriptionElement instanceof PsiDocTokenImpl){
					oldContent = oldContent + " " + ((PsiDocTokenImpl) descriptionElement).getText().replaceAll("\n"," ");
				}
			}
//			oldContent = field.getDocComment().getText();
		}
		LOG.info("fieldName: "+field.getName()+", doc: "+oldContent);
		/*if(oldContent.startsWith("//")){
//			oldContent = oldContent.replace("// ","// "+string+" ");
		}else if(oldContent.startsWith("*//**")){
		 String content = oldContent.replace("*//**\n","").replace("*//*","").replace("\n","").trim();
			oldContent = oldContent.replace(content,content.replace("* ","* "+string+" "));
		}*/
		return oldContent;
	}

	private PsiElement getPsiElement(AnActionEvent e) {
		PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
		Editor editor = e.getData(PlatformDataKeys.EDITOR);
		if (psiFile == null || editor == null || !(psiFile instanceof PsiJavaFileImpl)) {
			e.getPresentation().setEnabled(false);
			return null;
		}

		return psiFile.getNavigationElement();
	}
}
